package widgets;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

/**
 * This is an abstract class allowing for easy implementation of buttons with custom designs.
 *
 * @author Neil Dickson
 */
public abstract class CustomButton extends JComponent implements MouseListener {
	protected boolean isInside;
	protected boolean isPressed;
	protected boolean isEnabled;
	private ArrayList<ActionListener> listeners;
	private ArrayList<ActionInputListener> inputListeners;

	protected CustomButton() {
		this(true);
	}
	protected CustomButton(boolean isEnabled) {
		isPressed = false;
		isInside = false;
		this.isEnabled = isEnabled;
		listeners = new ArrayList<ActionListener>(1);
		inputListeners = null;
		addMouseListener(this);
		setOpaque(false);
		setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
	}

	public void mouseClicked(MouseEvent e) {

	}
	public void mousePressed(MouseEvent e) {
		if (e.getButton()==MouseEvent.BUTTON1 && isEnabled) {
			isPressed = true;
			repaint();
		}
	}
	public void mouseReleased(MouseEvent e) {
		if (e.getButton()==MouseEvent.BUTTON1 && isPressed) {
			isPressed = false;
			if (isInside && isEnabled) {
				announceAction(e);
			}
			repaint();
		}
	}
	public void mouseEntered(MouseEvent e) {
		isInside = true;
		repaint();
	}
	public void mouseExited(MouseEvent e) {
		isInside = false;
		repaint();
	}

	private void announceAction(InputEvent ie) {
		if (!listeners.isEmpty()) {
			ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "");
			for (ActionListener listener : listeners) {
				listener.actionPerformed(e);
			}
		}
		if (inputListeners!=null) {
			for (ActionInputListener listener : inputListeners) {
				listener.actionPerformed(ie);
			}
		}
	}

	public void addActionListener(ActionListener listener) {
		listeners.add(listener);
	}

	public void removeActionListener(ActionListener listener) {
		listeners.remove(listener);
	}

	public void addActionInputListener(ActionInputListener listener) {
		if (inputListeners==null) {
			inputListeners = new ArrayList<ActionInputListener>(1);
		}
		inputListeners.add(listener);
	}

	public void removeActionInputListener(ActionInputListener listener) {
		if (inputListeners!=null) {
			inputListeners.remove(listener);
		}
	}

	public boolean isInside() {
		return isInside;
	}
	public boolean isPressed() {
		return isPressed;
	}
	public boolean isEnabled() {
		return isEnabled;
	}
	public void setEnabled(boolean b) {
		if (isEnabled!=b) {
			isEnabled = b;
			if (!isEnabled) {
				isPressed = false;	// Just in case the button was down when disabled
			}
			repaint();
		}
	}
}
